package cn.tml.innermost.user.service.impl;

import cn.tml.innermost.framework.entity.enums.ResultCode;
import cn.tml.innermost.framework.exception.ServiceException;
import cn.tml.innermost.framework.security.AuthUser;
import cn.tml.innermost.framework.security.annotations.Login;
import cn.tml.innermost.framework.security.context.UserContext;
import cn.tml.innermost.framework.security.token.Token;
import cn.tml.innermost.framework.utils.EmailUtil;
import cn.tml.innermost.user.dos.Comment;
import cn.tml.innermost.user.dos.MusicRecord;
import cn.tml.innermost.user.dos.UserInfo;
import cn.tml.innermost.user.feign.UserToMusicFeignService;
import cn.tml.innermost.user.vos.params.*;
import cn.tml.innermost.user.vos.vo.*;
import cn.tml.innermost.user.mapper.CommentServerMapper;
import cn.tml.innermost.user.mapper.UserPlayRecordMapper;
import cn.tml.innermost.user.mapper.UserServerMapper;
import cn.tml.innermost.user.service.UserMusicListService;
import cn.tml.innermost.user.service.UserService;
import cn.tml.innermost.user.utils.BeanCopyUtil;
import cn.tml.innermost.user.utils.OssUtil;
import cn.tml.innermost.user.utils.UserTokenGenerate;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import static cn.tml.innermost.framework.security.enums.VerificationEnums.*;

@Slf4j
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserTokenGenerate userTokenGenerate;

    @Resource
    private UserMusicListService userMusicListService;

    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    @Autowired
    private UserServerMapper userServerMapper;

    @Autowired
    private UserPlayRecordMapper userPlayRecordMapper;

    @Resource
    private CommentServerMapper commentServerMapper;

    @Resource
    UserToMusicFeignService userToMusicFeignService;


//    @Resource
//    private EmailMapper emailMapper;

    @Autowired
    private EmailUtil emailUtil;

    @Override
    public Token Login(LoginByUserNameVO loginVO) {

        //从数据库查询用户名和密码
        LambdaQueryWrapper<UserInfo> lqDevice = new LambdaQueryWrapper<>();
        lqDevice.eq(UserInfo::getUsername, loginVO.getUsername());
        UserInfo user = userServerMapper.selectOne(lqDevice);

        if (!UserInfo.exist(user)) {
            //用户名错误
            throw new ServiceException(ResultCode.USER_USERNAME_ERROR);
        }
        if (user.getDeleteFlag()) {
            //用户已注销
            throw new ServiceException(ResultCode.USER_LOGOFF);
        }
        if (!user.getPassword().equals(loginVO.getPassword())) {
            //密码错误
            throw new ServiceException(ResultCode.USER_PASSWORD_ERROR);
        }
        return userTokenGenerate.createToken(user, true);
    }

    @Override
    public void sendEmailCode(EmailParams emailParams) {
        if (emailParams.getType().equals("1")) {//验证码类型为登录
            emailUtil.sendCode(emailParams.getEmailAddress(), "Innermost 登录的的验证码", LOGIN);
//            throw new ServiceException(ResultCode.SUCCESS);
        }
        if (emailParams.getType().equals("2")) {//验证码类型为注册
            emailUtil.sendCode(emailParams.getEmailAddress(), "Innermost 注册的的验证码", REGISTER);
//            throw new ServiceException(ResultCode.SUCCESS);
        }
        if (emailParams.getType().equals("3")) {//验证码类型为找回用户
//            throw new ServiceException(ResultCode.API_NOT_USE);
        }
        if (emailParams.getType().equals("4")) {//验证码类型为修改密码
            emailUtil.sendCode(emailParams.getEmailAddress(), "Innermost 修改密码的验证码", UPDATE_PASSWORD);
//            throw new ServiceException(ResultCode.SUCCESS);
        }
        if (emailParams.getType().equals("5")) {//验证码类型为支付钱包密码
//            throw new ServiceException(ResultCode.API_NOT_USE);
        }
//        throw new ServiceException(ResultCode.PARAMS_ERROR);
    }

    @Override
    public void changePassword(ChangePasswordParams changePasswordParams) {
        //对验证码进行验证（需要邮箱地址和验证码）
        boolean flag = emailUtil.verifyCode(changePasswordParams.getEmailAddress(), UPDATE_PASSWORD, changePasswordParams.getCode());

        if (!flag) {
            throw new ServiceException(ResultCode.VERIFICATION_EMAIL_CHECKED_ERROR);
        }
        //根据EmailAddress从数据库获取user信息
        UserInfo user = new UserInfo(changePasswordParams.getPassword(), changePasswordParams.getEmailAddress());

        LambdaQueryWrapper<UserInfo> lqDevice = new LambdaQueryWrapper<>();
        lqDevice.eq(UserInfo::getEmailAddress, user.getEmailAddress());
        UserInfo userInfo = userServerMapper.selectOne(lqDevice);

        if (userInfo == null) {
            //该邮箱未注册
            throw new ServiceException(ResultCode.USER_EMAIL_NOT_EXIST);
        }

        //对密码进行更新（根据id）
        userInfo.setPassword(changePasswordParams.getPassword());
        userServerMapper.updateById(userInfo);

//        Email email = new Email();
//        email.setId(userInfo.getId());
//        email.setEmailAddress(changePasswordParams.getEmailAddress());
//        email.setLoginName(changePasswordParams.getLoginName());
//        email.setPassword(changePasswordParams.getPassword());
//        emailMapper.updateById(email);
//        System.out.println(email);
        throw new ServiceException(ResultCode.USER_EDIT_SUCCESS);
    }

    @Override
    public Token loginByEmail(LoginByEmailVo loginByEmailVo) {
        //对验证码进行校验
        System.out.println(loginByEmailVo);
        boolean flag = emailUtil.verifyCode(loginByEmailVo.getEmailAddress(), LOGIN, loginByEmailVo.getCode());
        if (!flag) {
            throw new ServiceException(ResultCode.VERIFICATION_EMAIL_CHECKED_ERROR);
        }
        //通过邮箱地址获取user对象并生成token
        UserInfo user = new UserInfo();
        user.setEmailAddress(loginByEmailVo.getEmailAddress());
        LambdaQueryWrapper<UserInfo> lqDevice = new LambdaQueryWrapper<>();
        lqDevice.eq(UserInfo::getEmailAddress, user.getEmailAddress());
        UserInfo userInfo = userServerMapper.selectOne(lqDevice);

        if (userInfo == null) {
            throw new ServiceException(ResultCode.USER_NOT_EXIST);
        }

        return userTokenGenerate.createToken(userInfo, true);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Token Register(RegisterParams registerParams) {
        //验证验证码是否正确
//        if (!emailUtil.verifyCode(registerParams.getEmailAddress(), REGISTER, registerParams.getCode())) {
//            //验证码不正确抛出异常
//            throw new ServiceException(ResultCode.VERIFICATION_EMAIL_CHECKED_ERROR);
//        }

        UserInfo user = new UserInfo();
        BeanUtils.copyProperties(registerParams, user);


        //对账户名进行验证
        LambdaQueryWrapper<UserInfo> lqDevice1 = new LambdaQueryWrapper<>();
        lqDevice1.eq(UserInfo::getUsername, registerParams.getUsername());
        if (UserInfo.exist(userServerMapper.selectOne(lqDevice1))) {
            //账户名存在抛出异常
            throw new ServiceException(ResultCode.USER_NAME_EXIST);
        }

        //对邮箱进行验证
        LambdaQueryWrapper<UserInfo> lqDevice2 = new LambdaQueryWrapper<>();
        lqDevice2.eq(UserInfo::getEmailAddress, registerParams.getEmailAddress());
        if (UserInfo.exist(userServerMapper.selectOne(lqDevice2))) {
            //邮箱存在抛出异常
            throw new ServiceException(ResultCode.USER_EMAIL_EXIST);
        }
        log.info("USER::" + user);
        //插入数据
        try {
            userServerMapper.insert(user);
        } catch (Exception e) {
            //并发注册抛出异常
            throw new ServiceException(ResultCode.USER_REGISTER_ERROR);
        }

//        //调用创建歌单接口 获取歌单id 并更新用户默认歌单id
        MusicListVO likeMusic = userMusicListService.getRegisterMusicList("我喜欢的音乐", user.getUsername(), user.getId());

        //查询数据库并更新
        LambdaQueryWrapper<UserInfo> lqDevice = new LambdaQueryWrapper<>();
        lqDevice.eq(UserInfo::getEmailAddress, user.getEmailAddress());
        UserInfo userInfo = userServerMapper.selectOne(lqDevice);
        userInfo.setDefaultMusicListId(likeMusic.getId());
        userServerMapper.updateById(userInfo);
        //返回token
        return userTokenGenerate.createToken(userInfo, true);
    }

    @Override
    @Login(value = true)
    public UserInfoVO getUserInfo() {
        AuthUser authUser = UserContext.getCurrentUser();
        String username = authUser.getUsername();
        UserInfoVO redisValue = (UserInfoVO) redisTemplate.opsForValue().get("UserInfoUtil:" + authUser.getId());
        if (redisValue != null) {
            return redisValue;
        }
        //根据账户名进行查找
        LambdaQueryWrapper<UserInfo> lqDevice = new LambdaQueryWrapper<>();
        lqDevice.eq(UserInfo::getUsername, username);

        UserInfo user = userServerMapper.selectOne(lqDevice);

        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(user, userInfoVO);

        redisTemplate.opsForValue().set("UserInfoUtil:" + user.getId(), userInfoVO, 60 * 60, TimeUnit.SECONDS);

        return userInfoVO;
    }

    @Override
    public IdVO getUserId() {

        return new IdVO(UserContext.getCurrentUser().getId());
    }

    @Override
    public UpdateParams update(UpdateParams updateParams) {
        AuthUser authUser = UserContext.getCurrentUser();
        UserInfo updateUser = new UserInfo();
        BeanUtils.copyProperties(updateParams, updateUser);
        updateUser.setDefaultMusicListId(null);
        updateUser.setId(authUser.getId());
        //查看redis是否有用户信息数据 若有则跟新
        UserInfoVO redisValue = (UserInfoVO) redisTemplate.opsForValue().get("UserInfoUtil:" + authUser.getId());
        if (redisValue != null) {
            BeanUtils.copyProperties(updateParams, redisValue);
            redisTemplate.opsForValue().set("UserInfoUtil:" + authUser.getId(), redisValue, 60 * 60, TimeUnit.SECONDS);
        }
        userServerMapper.updateById(updateUser);
        return updateParams;
    }

    @Override
    public CommentsVO comments(CommentsParams commentsParams) {
        return null;
    }

    @Override
    public void editTheme(ThemeVO themevo) {
        AuthUser authUser = UserContext.getCurrentUser();
        UserInfo userInfo = new UserInfo();
        userInfo.setId(authUser.getId());
        userInfo.setTheme(themevo.getTheme());
        userServerMapper.updateById(userInfo);
    }

    @Override
    public void deleteUser(String userName) {
        //丛数据库中查找该用户
        LambdaQueryWrapper<UserInfo> lqDevice = new LambdaQueryWrapper<>();
        lqDevice.eq(UserInfo::getUsername, userName);
        UserInfo user = userServerMapper.selectOne(lqDevice);
        if (user == null) {
            //用户不存在
            throw new ServiceException(ResultCode.USER_NOT_EXIST);
        }
        if (user.getDeleteFlag()) {
            //用户已经删除
            throw new ServiceException(ResultCode.USER_LOGOFF);
        }

        //逻辑删除，将删除标记置为1
        user.setDeleteFlag(true);

        userServerMapper.updateById(user);
    }

    @Override
    public Page<UserInfoVO> selectUserPageVO(Integer Page) {
        //按页查询用户
        Page<UserInfo> users = userServerMapper.selectPage(new Page<>(Page, 15), new QueryWrapper<>());
        Page<UserInfoVO> userInfoVOPage = new Page<>();
        BeanUtils.copyProperties(users, userInfoVOPage);
        return userInfoVOPage;
    }

    @Override
    public void addUser(String userName, String password, String emailAddress) {
        //对账户名进行验证
        LambdaQueryWrapper<UserInfo> lqDevice1 = new LambdaQueryWrapper<>();
        lqDevice1.eq(UserInfo::getUsername, userName);

        if (UserInfo.exist(userServerMapper.selectOne(lqDevice1))) {
            throw new ServiceException(ResultCode.USER_NAME_EXIST);
        }

        //对邮箱进行验证
        LambdaQueryWrapper<UserInfo> lqDevice2 = new LambdaQueryWrapper<>();
        lqDevice2.eq(UserInfo::getEmailAddress, emailAddress);
        if (UserInfo.exist(userServerMapper.selectOne(lqDevice2))) {
            throw new ServiceException(ResultCode.USER_EMAIL_EXIST);
        }
        UserInfo user = new UserInfo(userName, password, emailAddress);
        userServerMapper.insert(user);
    }

    @Override
    public UserInfoVO selectUser(String userName) {
        LambdaQueryWrapper<UserInfo> lqDevice = new LambdaQueryWrapper<>();
        lqDevice.eq(UserInfo::getUsername, userName);
        UserInfo user = userServerMapper.selectOne(lqDevice);

        if (user == null) {
            //用户不存在
            throw new ServiceException(ResultCode.USER_NOT_EXIST);
        }

        if (user.getDeleteFlag()) {
            //用户已经删除
            throw new ServiceException(ResultCode.USER_LOGOFF);
        }
        UserInfoVO userInfoVo = new UserInfoVO();
        BeanUtils.copyProperties(user, userInfoVo);
        return userInfoVo;
    }

    @Override
    public UserInfoVO selectUser(Long id) {
        UserInfo userInfo = userServerMapper.selectById(id);
        if(!UserInfo.exist(userInfo)){
            throw new ServiceException(ResultCode.USER_NOT_EXIST);
        }
        UserInfoVO userInfoVO = new UserInfoVO();
        userInfoVO.setAvatar(userInfo.getAvatar());
        userInfoVO.setNickName(userInfo.getNickName());
        System.out.println();
        return userInfoVO;
    }

    @Override
    public void changeUserInfo(ChangeUserInfoParams changeUserInfoParams) {
        LambdaQueryWrapper<UserInfo> lqDevice = new LambdaQueryWrapper<>();
        lqDevice.eq(UserInfo::getUsername, changeUserInfoParams.getUserName());
        UserInfo userInfo = userServerMapper.selectOne(lqDevice);
        if (userInfo == null) {
            //用户不存在
            throw new ServiceException(ResultCode.USER_NOT_EXIST);
        }
        BeanUtils.copyProperties(changeUserInfoParams, userInfo);
        userServerMapper.updateById(userInfo);
    }

    @Override
    public String updUserProfile(MultipartFile file)  {
        AuthUser authUser = UserContext.getCurrentUser();
        String url = "";
        try {
            String fileName = file.getOriginalFilename();
            InputStream inputStream = file.getInputStream();
            url = OssUtil.SaveToOss(inputStream,fileName,authUser.getUsername()+"Avatar");
            UpdateParams newParams = new UpdateParams();
            newParams.setAvatar(url);
            //更新用户头像地址
            this.update(newParams);
        }catch (IOException e){
            e.printStackTrace();
            log.info("上传文件失败");
        }
        return url;
    }

    /**
     * 对于添加歌曲历史的高频写操作，这里redis采用两种key，
     * 一种为insertPlayRecord+id，此key用于插入的歌曲记录，定时进行数据库写入
     * 第二种为selectPlayRecord+id，此key用于查询歌曲记录，先查询insertPlayRecord，记录数不够用在查数据库
     * 查使用分页，所有的PlayRecord 都是按照时间倒叙排序
     * @return
     */

    @Override
    public List<MusicRecord> getPlayingRecord(PageParams musicRecordParams) {
        List<MusicRecord> res = new ArrayList<>();
        AuthUser authUser = UserContext.getCurrentUser();
        String username = authUser.getUsername();
        Long userId = authUser.getId();
        Integer startPage = musicRecordParams.getStartPage();
        Integer onePageAmount = musicRecordParams.getOnePageAmount();
        // 从redis中取出全部元素

        List<Object> range = redisTemplate.opsForList().range("insertPlayRecord" + userId, 0, -1);
        System.out.println(range);
        if(range != null){
            for (int i = (startPage-1)*onePageAmount;i<startPage*onePageAmount;i++){
                if(i>=range.size()){
                    break;
                }
                MusicRecord o = (MusicRecord)range.get(i);
                res.add(o);
            }
        }

//        如果redis中没有全部数据则从数据库中查询
        if(res.size()<onePageAmount){
            LocalDateTime createTime = null;
            if(res.size()>0){
//            因为列表本身是按照时间倒排的，因此最后一条数据就是最晚的数据，接下来从该条数据后面开始查询
                MusicRecord latest = res.get(res.size() - 1);
                createTime = latest.getCreateTime();
            }
            QueryWrapper<MusicRecord> queryWrapper = new QueryWrapper<>();
//            查询剩下的数据，数量为onePageAmount - res.size()，同时从res的最晚记录往后查询，可以避免查询到相同数据
            queryWrapper.eq("user_id", userId)
                    .orderByDesc("create_time")
                    .last("LIMIT "+(onePageAmount - res.size()));

            if(createTime!=null){
                queryWrapper.lt("create_time",createTime);
            }
            List<MusicRecord> records = userPlayRecordMapper.selectList(queryWrapper);
            res.addAll(records);
//            将数据存入redis中q
            if(!records.isEmpty()){
                redisTemplate.opsForList().rightPushAll("selectPlayRecord" + userId,records.toArray());
            }
        }
        return res;
    }

    /**
     * 删除记录需要从insertPlayRecord，selectPlayRecord以及数据库中删除
     * @param musicName
     */
    @Override
    public void deletePlayingRecord(String musicName) {
        Long userId = UserContext.getCurrentUser().getId();
        List<Object> insertPlayRecordRange = redisTemplate.opsForList().range("insertPlayRecord" + userId, 0, -1);

        if(insertPlayRecordRange!=null){
            for (Object o : insertPlayRecordRange) {
                if (((MusicRecord) o).getMusicName().equals(musicName)){
                    redisTemplate.opsForList().remove("insertPlayRecord" + userId,0,o);
                }
            }
        }
        List<Object> selectPlayRecordRange = redisTemplate.opsForList().range("selectPlayRecord" + userId, 0, -1);
        if(selectPlayRecordRange!=null){
            for (Object o : selectPlayRecordRange) {
                if (((MusicRecord) o).getMusicName().equals(musicName)){
                    redisTemplate.opsForList().remove("selectPlayRecord" + userId,0,o);
                }
            }
        }

        QueryWrapper<MusicRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",userId);
        queryWrapper.eq("music_name",musicName);
        userPlayRecordMapper.delete(queryWrapper);
    }

    @Override
    public void addMusicRecord(MusicVO music) {
        AuthUser authUser = UserContext.getCurrentUser();
        String username = authUser.getUsername();
        Long userId = authUser.getId();
        MusicRecord musicRecord = new MusicRecord();
        BeanUtils.copyProperties(music, musicRecord);
        musicRecord.setUserId(userId);
        redisTemplate.opsForList().rightPush("insertPlayRecord"+userId,musicRecord);

    }

    @Override
    public void commentMusic(CommentMusicParams commentMusicParams) {
        Comment comment = new Comment();
        BeanUtils.copyProperties(commentMusicParams, comment);
        comment.setUserId(UserContext.getCurrentUser().getId());
        comment.setDel_flag(false);
        if(commentMusicParams.getRootId() == null) {
            comment.setRootId(-1L);
        }
        if(commentMusicParams.getToCommentUserId() == null){
            comment.setToCommentUserId(-1L);
        }
        comment.setMusicListId(-1L);
        commentServerMapper.insert(comment);
    }

    @Override
    public void commentMusicList(CommentMusicListParams commentMusicListParams) {
        Comment comment = new Comment();
        BeanUtils.copyProperties(commentMusicListParams, comment);
        comment.setUserId(UserContext.getCurrentUser().getId());
        comment.setDel_flag(false);
        if(commentMusicListParams.getRootId() == null){
            comment.setRootId(-1L);
        }
        if(commentMusicListParams.getToCommentUserId() == null){
            comment.setToCommentUserId(-1L);
        }
        comment.setMusicId(-1L);
        commentServerMapper.insert(comment);
    }

    @Override
    public Page<MusicCommentVO> getMusicComment(Long musicId, int page, int size) {
        QueryWrapper<Comment> lq = new QueryWrapper<>();
        lq.eq("music_id", musicId)
                .eq("root_id", -1);
        Page<Comment> commentPage = commentServerMapper.selectPage(new Page<>(page, size), lq);
        Page<MusicCommentVO> musicCommentVOPage = BeanCopyUtil.copyPageProperties(commentPage, MusicCommentVO::new, page, size);
        for (MusicCommentVO musicCommentVO : musicCommentVOPage.getRecords()){
            UserInfo userInfo = userServerMapper.selectById(musicCommentVO.getUserId());
            musicCommentVO.setNickName(userInfo.getNickName());
            musicCommentVO.setAvatar(userInfo.getAvatar());
        }
        return musicCommentVOPage;
    }

    @Override
    public Page<MusicListCommentVO> getMusicListComment(Long MusicListId, int page, int size) {
        QueryWrapper<Comment> lq = new QueryWrapper<>();
        lq.eq("MusicList_id", MusicListId)
                .eq("root_id", -1);
        Page<Comment> commentPage = commentServerMapper.selectPage(new Page<>(page, size), lq);
        Page<MusicListCommentVO> MusicListCommentVOPage = BeanCopyUtil.copyPageProperties(commentPage, MusicListCommentVO::new, page, size);
        for (MusicListCommentVO MusicListCommentVO : MusicListCommentVOPage.getRecords()){
            UserInfo userInfo = userServerMapper.selectById(MusicListCommentVO.getUserId());
            MusicListCommentVO.setNickName(userInfo.getNickName());
            MusicListCommentVO.setAvatar(userInfo.getAvatar());
        }
        return MusicListCommentVOPage;
    }

    @Override
    public Page<MusicCommentVO> getMusicSubComment(Long rootId, int page, int size) {
        QueryWrapper<Comment> lq = new QueryWrapper<>();
        lq.eq("root_id", rootId);
        Page<Comment> commentPage = commentServerMapper.selectPage(new Page<>(page, size), lq);
        Page<MusicCommentVO> musicCommentVOPage = BeanCopyUtil.copyPageProperties(commentPage, MusicCommentVO::new, page, size);
        for (MusicCommentVO musicCommentVO : musicCommentVOPage.getRecords()){
            UserInfo userInfo = userServerMapper.selectById(musicCommentVO.getUserId());
            musicCommentVO.setNickName(userInfo.getNickName());
            musicCommentVO.setAvatar(userInfo.getAvatar());
        }
        return musicCommentVOPage;
    }

    @Override
    public Page<MusicListCommentVO> getMusicListSubComment(Long rootId, int page, int size) {
        QueryWrapper<Comment> lq = new QueryWrapper<>();
        lq.eq("root_id", rootId);
        Page<Comment> commentPage = commentServerMapper.selectPage(new Page<>(page, size), lq);
        Page<MusicListCommentVO> MusicListCommentVOPage = BeanCopyUtil.copyPageProperties(commentPage, MusicListCommentVO::new, page, size);
        for (MusicListCommentVO MusicListCommentVO : MusicListCommentVOPage.getRecords()){
            UserInfo userInfo = userServerMapper.selectById(MusicListCommentVO.getUserId());
            MusicListCommentVO.setNickName(userInfo.getNickName());
            MusicListCommentVO.setAvatar(userInfo.getAvatar());
        }
        return MusicListCommentVOPage;
    }

    @Override
    public void deleteComment(Long id) {
        Comment comment = commentServerMapper.selectById(id);
        if(!comment.getUserId().equals(UserContext.getCurrentUser().getId())){
            throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
        }
        commentServerMapper.deleteById(id);
    }

    @Override
    public boolean redisTest() {
        redisTemplate.opsForValue().set("PlayRecord:123:1", 1);
        System.out.println(redisTemplate.keys("PlayRecord:123*").size());
        System.out.println(redisTemplate.opsForValue().multiGet(redisTemplate.keys("PlayRecord:123*")));
        return false;
    }

    /**
     * 先查询数据库是否有record，如果有则更新时间，如果没有则插入
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void  executeInsertMusicRecordTask(){
        Set<String> keys = redisTemplate.keys("insertPlayRecord*");
        List<Object> values = redisTemplate.opsForValue().multiGet(keys);
//        此map用于统计当天一首歌曲被播放过多少次，id为k，次数为v
        HashMap<Long,Integer> increaseListenCount = new HashMap<>();
        MusicRecord newRecord = null;
        for (int i = 0; i < values.size(); i++) {
             newRecord = (MusicRecord) values.get(i);
            Long musicId = newRecord.getMusicId();
            Long userId = newRecord.getUserId();
            increaseListenCount.put(musicId,increaseListenCount.getOrDefault(musicId,0)+1);
            QueryWrapper<MusicRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("music_id",musicId).eq("user_id",userId);
            MusicRecord record = userPlayRecordMapper.selectOne(queryWrapper);
            if(record != null){
                record.setCreateTime(newRecord.getCreateTime());
                userPlayRecordMapper.updateById(record);
            }else {
                userPlayRecordMapper.insert(newRecord);
            }
        }
        increaseListenCount.forEach((k,v)->{
            userToMusicFeignService.incrMusicListenCount(k,v);
        });
    }
}
